const webpack = require("webpack");
const CompressionWebpackPlugin = require("compression-webpack-plugin");
const VueFilenameInjector = require("@d2-projects/vue-filename-injector");
const TerserPlugin = require("terser-webpack-plugin");
const { each, keys } = require("lodash");

// 拼接路径
const resolve = (dir) => require("path").join(__dirname, dir);

// 增加环境变量
process.env.VUE_APP_VERSION = Date.now();
process.env.VUE_APP_BUILD_TIME = require("dayjs")().format("YYYY-M-D HH:mm:ss");

const pages = {
  index: {
    entry: "src/main.js",
    template: "public/index.html",
    filename: "index.html",
    chunks: [
      "manifest",
      "index",
      "chunk-index",
      "chunk-vendor",
      "chunk-common",
      "chunk-vue",
      "chunk-element",
    ],
  },
};

// 这里必须要设置成空，目前发现的问题是，多页适配(pages)中，如果设置成/，打包后，找不到资源
let publicPath = "";

module.exports = {
  // 根据你的实际情况更改这里
  publicPath,
  lintOnSave: false,
  outputDir: process.env.VUE_BASE_DIR,
  devServer: {
    publicPath, // 和 publicPath 保持一致
    disableHostCheck: false, // 关闭 host check，方便使用 ngrok 之类的内网转发工具
    proxy: {
      "/api": {
        target: process.env.VUE_APP_API,
        changeOrigin: true,
        ws: false,
        pathRewrite: {
          "^/api": "",
        },
      },
    },
  },
  pages,
  configureWebpack: () => {
    const configNew = {};
    if (process.env.NODE_ENV === "production") {
      configNew.externals = {
        T: "T", // 天地图
      };
      configNew.plugins = [
        // gzip
        new CompressionWebpackPlugin({
          filename: "[path].gz[query]",
          test: new RegExp("\\.(" + ["js", "css"].join("|") + ")$"),
          threshold: 10240,
          minRatio: 0.8,
          deleteOriginalAssets: false,
        }),
        new TerserPlugin({
          terserOptions: {
            ecma: undefined,
            warnings: false,
            parse: {},
            compress: {
              drop_console: true, // 清除 console 语句
              drop_debugger: false, // 清除 debugger 语句
              pure_funcs: ["console.log"], // 移除console
            },
          },
        }),
      ];
    }
    return configNew;
  },
  chainWebpack: (config) => {
    //忽略/moment/locale下的所有文件
    config.plugin("ignore").use(new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/));
    config.optimization.runtimeChunk({
      name: "manifest",
    });
    config.optimization.splitChunks({
      cacheGroups: {
        // External dependencies common to all pages
        libs: {
          name: "chunk-vendor",
          chunks: "initial",
          minChunks: 1,
          test: /[\\/]node_modules[\\/]/,
          priority: 1,
          reuseExistingChunk: true,
          enforce: true,
        },
        // Code common to all pages
        common: {
          name: "chunk-common",
          chunks: "initial",
          minChunks: 2,
          maxInitialRequests: 5,
          minSize: 0,
          priority: 2,
          reuseExistingChunk: true,
          enforce: true,
        },
        // External dependencies that are only used by the index page
        index: {
          name: "chunk-index",
          chunks: "all",
          minChunks: 1,
          test: /[\\/]node_modules[\\/](screenfull|nprogress|hotkeys-js|fuse\.js|better-scroll|lowdb)[\\/]/,
          priority: 3,
          reuseExistingChunk: true,
          enforce: true,
        },
        // only vant
        sign: {
          name: "chunk-sign",
          chunks: "all",
          minChunks: 1,
          test: /[\\/]node_modules[\\/](vant)[\\/]/,
          priority: 3,
          reuseExistingChunk: true,
          enforce: true,
        },
        // Vue family packages
        vue: {
          name: "chunk-vue",
          test: /[\\/]node_modules[\\/](vue|vue-router|vuex)[\\/]/,
          chunks: "all",
          priority: 3,
          reuseExistingChunk: true,
          enforce: true,
        },
        // only element-ui
        element: {
          name: "chunk-element",
          test: /[\\/]node_modules[\\/]element-ui[\\/]/,
          chunks: "all",
          priority: 3,
          reuseExistingChunk: true,
          enforce: true,
        },
      },
    });
    each(keys(pages), (name) => {
      config.plugins.delete(`prefetch-${name}`);
      config.plugins.delete(`preload-${name}`);
    });
    // 解决 cli3 热更新失效 https://github.com/vuejs/vue-cli/issues/1559
    config.resolve.symlinks(true);

    config
      // 开发环境 sourcemap 不包含列信息
      .when(process.env.NODE_ENV === "development", (config) => config.devtool("cheap-source-map"))
      // 预览环境构建 vue-loader 添加 filename
      .when(process.env.VUE_APP_SCOURCE_LINK === "TRUE", (config) =>
        VueFilenameInjector(config, {
          propName: process.env.VUE_APP_SOURCE_VIEWER_PROP_NAME,
        })
      );

    // bpmn
    const bpmnRule = config.module.rule("bpmn");
    bpmnRule
      .test(/\.bpmn$/i)
      .use("raw-loader")
      .loader("raw-loader")
      .end();
    // svg
    const svgRule = config.module.rule("svg");
    svgRule.uses.clear();
    svgRule.include
      .add(resolve("src/assets/svg-icons/icons"))
      .end()
      .use("svg-sprite-loader")
      .loader("svg-sprite-loader")
      .options({
        symbolId: "d2-[name]",
      })
      .end();
    // image exclude
    const imagesRule = config.module.rule("images");
    imagesRule
      .test(/\.(png|jpe?g|gif|webp|svg)(\?.*)?$/)
      .exclude.add(resolve("src/assets/svg-icons/icons"))
      .end();
    // 重新设置 alias
    config.resolve.alias
      .set("api", resolve("src/api"))
      .set("assets", resolve("src/assets"))
      .set("components", resolve("src/components"))
      .set("mixins", resolve("src/mixins"))
      .set("views", resolve("src/views"))
      .set("store", resolve("src/store"))
      .set("plugin", resolve("src/plugin"))
      .set("util", resolve("src/util"))
      .set("libs", resolve("src/libs"))
      .set("router", resolve("src/router"));
    // 分析工具
    if (process.env.npm_config_report) {
      config
        .plugin("webpack-bundle-analyzer")
        .use(require("webpack-bundle-analyzer").BundleAnalyzerPlugin);
    }
  },
  // 不输出 map 文件
  productionSourceMap: false,
  css: {
    extract: true,
    sourceMap: false,
    requireModuleExtension: true,
    loaderOptions: {
      sass: {
        prependData: `
        @import "~@/assets/style/mixin.scss";
        @import '~@/assets/style/public.scss';
        @import '~@/assets/style/var.scss';
      `,
      },
    },
  },
};
